package org.example.zuul.filter.post;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import org.example.zuul.filter.ZuulFilter;
import org.example.zuul.http.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.ResponseEntity;

public class SendResponseFilter implements ZuulFilter {
    private static final Logger LOGGER = LoggerFactory.getLogger(SendResponseFilter.class);

    @Override
    public void run() {
        addResponseHeaders();
        try {
            writeResponse();
        } catch (Exception e) {
            LOGGER.error("write response exception", e);
        }
    }

    @Override
    public int filterOrder() {
        return 1;
    }

    @Override
    public String filterType() {
        return ZuulFilter.TYPE_POST;
    }

    private void addResponseHeaders() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        HttpHeaders httpHeaders = ctx.getResponseEntity().getHeaders();
        for (Map.Entry<String, List<String>> entry : httpHeaders.entrySet()) {
            String headerName = entry.getKey();
            for (String headValue : entry.getValue()) {
                response.addHeader(headerName, headValue);
            }
        }
    }

    private void writeResponse() throws Exception{
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletResponse response = ctx.getResponse();
        if (response.getCharacterEncoding() == null) {
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
        }
        ResponseEntity<byte[]> responseEntity = ctx.getResponseEntity();
        byte[] body = responseEntity.getBody();
        if (body != null) {
            ServletOutputStream outputStream = response.getOutputStream();
            outputStream.write(body);
            outputStream.flush();
        }
    }
}
